﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using PdfSharp.Drawing;
using VAdvantage.Utility;
using VAdvantage.Classes;
using VAdvantage.Model;
using System.IO;
using VAdvantage.Logging;
using System.Threading;
using System.Windows.Media.Imaging;

namespace VAdvantage.Print
{
    public class ImageElement : PrintElement
    {
        public static ImageElement Get(String imageURLString)
        {
            Object key = imageURLString;
            ImageElement image = null;
            if (s_cache.ContainsKey(key))
                image = (ImageElement)s_cache[key];

            if (image == null)
            {
                image = new ImageElement(imageURLString);
                s_cache[key] = image;
            }
            return new ImageElement(image.GetImage(), imageURLString);
        }	//	get


        public static ImageElement Get(int AD_PrintFormatItem_ID)
        {
            Object key = AD_PrintFormatItem_ID;
            ImageElement image = null;
            if (s_cache.ContainsKey(key))
                image = (ImageElement)s_cache[key];
            if (image == null)
            {
                image = new ImageElement(AD_PrintFormatItem_ID);
                s_cache[key] = image;
            }
            return new ImageElement(image.GetImage(), "AD_PrintFormatItem_ID=" + AD_PrintFormatItem_ID);
        }	//	get


        /// <summary>
        /// Get the Image
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static ImageElement Get(Image image)
        {
            return new ImageElement(image, "Custom Image");
        }

        public ImageElement(Image image, String info)
        {
            m_image = image;
            p_info = info;
            if (m_image != null)
                log.Fine("Image=" + info + " - " + image);
            else
                log.Log(Level.WARNING, "Image is NULL");
        }	//	ImageElement

        private ImageElement(int AD_PrintFormatItem_ID)
        {
            LoadAttachment(AD_PrintFormatItem_ID);
        }	//	ImageElement

        private ImageElement(String imageURLstring)
        {
            p_info = imageURLstring;
            string imageURL = GetURL(imageURLstring);
            if (imageURL != null)
            {
                bool uploaded = false;
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    m_image = new Image();
                    ImageSource imgS = VAdvantage.Utility.Envs.LoadImageSource(imageURLstring);
                    m_image.Source = imgS;
                    //m_image = Image.FromStream(Envs.GetImageStream(imageURLstring));
                    uploaded = true;
                });

                while (!uploaded)
                    Thread.Sleep(10);

                uploaded = false;

                if (m_image != null)
                    log.Fine("URL=" + imageURL);
                else
                    log.Log(Level.WARNING, "Not loaded - URL=" + imageURL);
            }
            else
                log.Log(Level.WARNING, "Invalid URL=" + imageURLstring);
        }	//	ImageElement

        private string GetURL(string imageURLstring)
        {
            return imageURLstring;
        }



        /**	The Image			*/
        private Image m_image = null;
        /** Scale				*/
        private double m_scaleFactor = 1;

        /**	60 minute Cache						*/
        private static CCache<Object, ImageElement> s_cache = new CCache<Object, ImageElement>("ImageElement", 10, 60);

        /// <summary>
        /// Image
        /// </summary>
        /// <returns></returns>
        public Image GetImage()
        {
            return m_image;
        }	//	getImage


        private void LoadAttachment(int AD_PrintFormatItem_ID)
        {
            MAttachment attachment = MAttachment.Get(VAdvantage.Utility.Envs.GetCtx(), MPrintFormatItem.Table_ID, AD_PrintFormatItem_ID);
            if (attachment == null)
            {
                log.Log(Level.WARNING, "No Attachment - AD_PrintFormatItem_ID=" + AD_PrintFormatItem_ID);
                return;
            }
            if (attachment.GetEntryCount() != 1)
            {
                log.Log(Level.WARNING, "Need just 1 Attachment Entry = " + attachment.GetEntryCount());
                return;
            }
            p_info = attachment.GetEntryName(0);
            byte[] imageData = attachment.GetEntryData(0);
            if (imageData != null)
            {
                MemoryStream ms = new MemoryStream(imageData);
                BitmapImage bi = new BitmapImage();
                bi.SetSource(ms);
                m_image.Source = bi;
            }
            if (m_image != null)
                log.Fine(attachment.GetEntryName(0) + " - Size=" + imageData.Length);
            else
                log.Log(Level.WARNING, attachment.GetEntryName(0) + " - not loaded (must be gif or jpg) - AD_PrintFormatItem_ID=" + AD_PrintFormatItem_ID);
        }	//	loadAttachment

        protected override bool CalculateSize()
        {
            p_width = 0;
            p_height = 0;
            if (m_image == null)
                return true;
            //	we have an image
            WaitForLoad(m_image);
            if (m_image != null)
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    p_width = m_image.Width;
                    p_height = m_image.Height;
                });

                Thread.Sleep(20);

                if (p_width * p_height == 0)
                    return true;	//	don't bother scaling and prevent div by 0

                // 0 = unlimited so scale to fit restricted dimension
                if (p_maxWidth * p_maxHeight != 0)	// scale to maintain aspect ratio
                {
                    if (p_width / p_height > p_maxWidth / p_maxHeight)
                        // image "fatter" than available area
                        m_scaleFactor = p_maxWidth / p_width;
                    else
                        m_scaleFactor = p_maxHeight / p_height;
                }
                p_width = (double)m_scaleFactor * p_width;
                p_height = (double)m_scaleFactor * p_height;
            }
            return true;
        }	//	calculateSize


        public override void PaintPdf(XGraphics g2D, int pageNo, XPoint pageStart, Ctx ctx, bool isView)
        {
            if (m_image == null)
                return;

            //	Position
            XPoint location = GetAbsoluteLocation(pageStart);
            double x = location.X;
            if (MPrintFormatItem.FIELDALIGNMENTTYPE_TrailingRight.Equals(p_FieldAlignmentType))
                x += p_maxWidth - p_width;
            else if (MPrintFormatItem.FIELDALIGNMENTTYPE_Center.Equals(p_FieldAlignmentType))
                x += (p_maxWidth - p_width) / 2;
            double y = location.Y;

            // 	map a scaled and shifted version of the image to device space
            //g2D.ScaleTransform(m_scaleFactor, m_scaleFactor);

            //g2D.DrawImage(m_image, p_width, p_height, (double)x, (double)y);
            //g2D.ResetTransform();
        }	//	paint


        public override Query GetDrillDown(Point relativePoint, int pageNo)
        {
            return null;
        }

        public override Query GetDrillAcross(Point relativePoint, int pageNo)
        {
            return null;
        }

        public override void Paint(Canvas g2D, int pageNo, XPoint pageStart, Ctx ctx, bool isView)
        {
            if (m_image == null)
                return;

            //	Position
            XPoint location = GetAbsoluteLocation(pageStart);
            double x = location.X;
            if (MPrintFormatItem.FIELDALIGNMENTTYPE_TrailingRight.Equals(p_FieldAlignmentType))
                x += p_maxWidth - p_width;
            else if (MPrintFormatItem.FIELDALIGNMENTTYPE_Center.Equals(p_FieldAlignmentType))
                x += (p_maxWidth - p_width) / 2;
            double y = location.Y;

            if (m_image != null)
            {
                try
                {
                    m_image.Margin = new Thickness(x, y, 0, 0);
                    if(g2D.Children.IndexOf(m_image) < 0)
                        g2D.Children.Add(m_image);
                }
                catch
                {
                }
            }
        }

    }
}
